home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / Net / URL.php < prev    next >
PHP Script  |  2004-10-01  |  14KB  |  411 lines

  1. <?php
  2. // +-----------------------------------------------------------------------+
  3. // | Copyright (c) 2002-2004, Richard Heyes                                |
  4. // | All rights reserved.                                                  |
  5. // |                                                                       |
  6. // | Redistribution and use in source and binary forms, with or without    |
  7. // | modification, are permitted provided that the following conditions    |
  8. // | are met:                                                              |
  9. // |                                                                       |
  10. // | o Redistributions of source code must retain the above copyright      |
  11. // |   notice, this list of conditions and the following disclaimer.       |
  12. // | o Redistributions in binary form must reproduce the above copyright   |
  13. // |   notice, this list of conditions and the following disclaimer in the |
  14. // |   documentation and/or other materials provided with the distribution.|
  15. // | o The names of the authors may not be used to endorse or promote      |
  16. // |   products derived from this software without specific prior written  |
  17. // |   permission.                                                         |
  18. // |                                                                       |
  19. // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |
  20. // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |
  21. // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
  22. // | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |
  23. // | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
  24. // | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |
  25. // | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
  26. // | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
  27. // | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |
  28. // | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
  29. // | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |
  30. // |                                                                       |
  31. // +-----------------------------------------------------------------------+
  32. // | Author: Richard Heyes <richard at php net>                            |
  33. // +-----------------------------------------------------------------------+
  34. //
  35. // $Id: URL.php,v 1.36 2004/06/19 18:58:50 richard Exp $
  36. //
  37. // Net_URL Class
  38.  
  39. class Net_URL
  40. {
  41.     /**
  42.     * Full url
  43.     * @var string
  44.     */
  45.     var $url;
  46.  
  47.     /**
  48.     * Protocol
  49.     * @var string
  50.     */
  51.     var $protocol;
  52.  
  53.     /**
  54.     * Username
  55.     * @var string
  56.     */
  57.     var $username;
  58.  
  59.     /**
  60.     * Password
  61.     * @var string
  62.     */
  63.     var $password;
  64.  
  65.     /**
  66.     * Host
  67.     * @var string
  68.     */
  69.     var $host;
  70.  
  71.     /**
  72.     * Port
  73.     * @var integer
  74.     */
  75.     var $port;
  76.  
  77.     /**
  78.     * Path
  79.     * @var string
  80.     */
  81.     var $path;
  82.  
  83.     /**
  84.     * Query string
  85.     * @var array
  86.     */
  87.     var $querystring;
  88.  
  89.     /**
  90.     * Anchor
  91.     * @var string
  92.     */
  93.     var $anchor;
  94.  
  95.     /**
  96.     * Whether to use []
  97.     * @var bool
  98.     */
  99.     var $useBrackets;
  100.  
  101.     /**
  102.     * PHP4 Constructor
  103.     *
  104.     * @see __construct()
  105.     */
  106.     function Net_URL($url = null, $useBrackets = true)
  107.     {
  108.         $this->__construct($url, $useBrackets);
  109.     }
  110.  
  111.     /**
  112.     * PHP5 Constructor
  113.     *
  114.     * Parses the given url and stores the various parts
  115.     * Defaults are used in certain cases
  116.     *
  117.     * @param string $url         Optional URL
  118.     * @param bool   $useBrackets Whether to use square brackets when
  119.     *                            multiple querystrings with the same name
  120.     *                            exist
  121.     */
  122.     function __construct($url = null, $useBrackets = true)
  123.     {
  124.         $HTTP_SERVER_VARS  = !empty($_SERVER) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
  125.  
  126.         $this->useBrackets = $useBrackets;
  127.         $this->url         = $url;
  128.         $this->user        = '';
  129.         $this->pass        = '';
  130.         $this->host        = '';
  131.         $this->port        = 80;
  132.         $this->path        = '';
  133.         $this->querystring = array();
  134.         $this->anchor      = '';
  135.  
  136.         // Only use defaults if not an absolute URL given
  137.         if (!preg_match('/^[a-z0-9]+:\/\//i', $url)) {
  138.  
  139.             $this->protocol    = (@$HTTP_SERVER_VARS['HTTPS'] == 'on' ? 'https' : 'http');
  140.  
  141.             /**
  142.             * Figure out host/port
  143.             */
  144.             if (!empty($HTTP_SERVER_VARS['HTTP_HOST']) AND preg_match('/^(.*)(:([0-9]+))?$/U', $HTTP_SERVER_VARS['HTTP_HOST'], $matches)) {
  145.                 $host = $matches[1];
  146.                 if (!empty($matches[3])) {
  147.                     $port = $matches[3];
  148.                 } else {
  149.                     $port = $this->getStandardPort($this->protocol);
  150.                 }
  151.             }
  152.  
  153.             $this->user        = '';
  154.             $this->pass        = '';
  155.             $this->host        = !empty($host) ? $host : (isset($HTTP_SERVER_VARS['SERVER_NAME']) ? $HTTP_SERVER_VARS['SERVER_NAME'] : 'localhost');
  156.             $this->port        = !empty($port) ? $port : (isset($HTTP_SERVER_VARS['SERVER_PORT']) ? $HTTP_SERVER_VARS['SERVER_PORT'] : $this->getStandardPort($this->protocol));
  157.             $this->path        = !empty($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : '/';
  158.             $this->querystring = isset($HTTP_SERVER_VARS['QUERY_STRING']) ? $this->_parseRawQuerystring($HTTP_SERVER_VARS['QUERY_STRING']) : null;
  159.             $this->anchor      = '';
  160.         }
  161.  
  162.         // Parse the url and store the various parts
  163.         if (!empty($url)) {
  164.             $urlinfo = parse_url($url);
  165.  
  166.             // Default querystring
  167.             $this->querystring = array();
  168.  
  169.             foreach ($urlinfo as $key => $value) {
  170.                 switch ($key) {
  171.                     case 'scheme':
  172.                         $this->protocol = $value;
  173.                         $this->port     = $this->getStandardPort($value);
  174.                         break;
  175.  
  176.                     case 'user':
  177.                     case 'pass':
  178.                     case 'host':
  179.                     case 'port':
  180.                         $this->$key = $value;
  181.                         break;
  182.  
  183.                     case 'path':
  184.                         if ($value{0} == '/') {
  185.                             $this->path = $value;
  186.                         } else {
  187.                             $path = dirname($this->path) == DIRECTORY_SEPARATOR ? '' : dirname($this->path);
  188.                             $this->path = sprintf('%s/%s', $path, $value);
  189.                         }
  190.                         break;
  191.  
  192.                     case 'query':
  193.                         $this->querystring = $this->_parseRawQueryString($value);
  194.                         break;
  195.  
  196.                     case 'fragment':
  197.                         $this->anchor = $value;
  198.                         break;
  199.                 }
  200.             }
  201.         }
  202.     }
  203.  
  204.     /**
  205.     * Returns full url
  206.     *
  207.     * @return string Full url
  208.     * @access public
  209.     */
  210.     function getURL()
  211.     {
  212.         $querystring = $this->getQueryString();
  213.  
  214.         $this->url = $this->protocol . '://'
  215.                    . $this->user . (!empty($this->pass) ? ':' : '')
  216.                    . $this->pass . (!empty($this->user) ? '@' : '')
  217.                    . $this->host . ($this->port == $this->getStandardPort($this->protocol) ? '' : ':' . $this->port)
  218.                    . $this->path
  219.                    . (!empty($querystring) ? '?' . $querystring : '')
  220.                    . (!empty($this->anchor) ? '#' . $this->anchor : '');
  221.  
  222.         return $this->url;
  223.     }
  224.  
  225.     /**
  226.     * Adds a querystring item
  227.     *
  228.     * @param  string $name       Name of item
  229.     * @param  string $value      Value of item
  230.     * @param  bool   $preencoded Whether value is urlencoded or not, default = not
  231.     * @access public
  232.     */
  233.     function addQueryString($name, $value, $preencoded = false)
  234.     {
  235.         if ($preencoded) {
  236.             $this->querystring[$name] = $value;
  237.         } else {
  238.             $this->querystring[$name] = is_array($value) ? array_map('rawurlencode', $value): rawurlencode($value);
  239.         }
  240.     }
  241.  
  242.     /**
  243.     * Removes a querystring item
  244.     *
  245.     * @param  string $name Name of item
  246.     * @access public
  247.     */
  248.     function removeQueryString($name)
  249.     {
  250.         if (isset($this->querystring[$name])) {
  251.             unset($this->querystring[$name]);
  252.         }
  253.     }
  254.  
  255.     /**
  256.     * Sets the querystring to literally what you supply
  257.     *
  258.     * @param  string $querystring The querystring data. Should be of the format foo=bar&x=y etc
  259.     * @access public
  260.     */
  261.     function addRawQueryString($querystring)
  262.     {
  263.         $this->querystring = $this->_parseRawQueryString($querystring);
  264.     }
  265.  
  266.     /**
  267.     * Returns flat querystring
  268.     *
  269.     * @return string Querystring
  270.     * @access public
  271.     */
  272.     function getQueryString()
  273.     {
  274.         if (!empty($this->querystring)) {
  275.             foreach ($this->querystring as $name => $value) {
  276.                 if (is_array($value)) {
  277.                     foreach ($value as $k => $v) {
  278.                         $querystring[] = $this->useBrackets ? sprintf('%s[%s]=%s', $name, $k, $v) : ($name . '=' . $v);
  279.                     }
  280.                 } elseif (!is_null($value)) {
  281.                     $querystring[] = $name . '=' . $value;
  282.                 } else {
  283.                     $querystring[] = $name;
  284.                 }
  285.             }
  286.             $querystring = implode(ini_get('arg_separator.output'), $querystring);
  287.         } else {
  288.             $querystring = '';
  289.         }
  290.  
  291.         return $querystring;
  292.     }
  293.  
  294.     /**
  295.     * Parses raw querystring and returns an array of it
  296.     *
  297.     * @param  string  $querystring The querystring to parse
  298.     * @return array                An array of the querystring data
  299.     * @access private
  300.     */
  301.     function _parseRawQuerystring($querystring)
  302.     {
  303.         $parts  = preg_split('/[' . preg_quote(ini_get('arg_separator.input'), '/') . ']/', $querystring, -1, PREG_SPLIT_NO_EMPTY);
  304.         $return = array();
  305.  
  306.         foreach ($parts as $part) {
  307.             if (strpos($part, '=') !== false) {
  308.                 $value = substr($part, strpos($part, '=') + 1);
  309.                 $key   = substr($part, 0, strpos($part, '='));
  310.             } else {
  311.                 $value = null;
  312.                 $key   = $part;
  313.             }
  314.             if (substr($key, -2) == '[]') {
  315.                 $key = substr($key, 0, -2);
  316.                 if (@!is_array($return[$key])) {
  317.                     $return[$key]   = array();
  318.                     $return[$key][] = $value;
  319.                 } else {
  320.                     $return[$key][] = $value;
  321.                 }
  322.             } elseif (!$this->useBrackets AND !empty($return[$key])) {
  323.                 $return[$key]   = (array)$return[$key];
  324.                 $return[$key][] = $value;
  325.             } else {
  326.                 $return[$key] = $value;
  327.             }
  328.         }
  329.  
  330.         return $return;
  331.     }
  332.  
  333.     /**
  334.     * Resolves //, ../ and ./ from a path and returns
  335.     * the result. Eg:
  336.     *
  337.     * /foo/bar/../boo.php    => /foo/boo.php
  338.     * /foo/bar/../../boo.php => /boo.php
  339.     * /foo/bar/.././/boo.php => /foo/boo.php
  340.     *
  341.     * This method can also be called statically.
  342.     *
  343.     * @param  string $url URL path to resolve
  344.     * @return string      The result
  345.     */
  346.     function resolvePath($path)
  347.     {
  348.         $path = explode('/', str_replace('//', '/', $path));
  349.  
  350.         for ($i=0; $i<count($path); $i++) {
  351.             if ($path[$i] == '.') {
  352.                 unset($path[$i]);
  353.                 $path = array_values($path);
  354.                 $i--;
  355.  
  356.             } elseif ($path[$i] == '..' AND ($i > 1 OR ($i == 1 AND $path[0] != '') ) ) {
  357.                 unset($path[$i]);
  358.                 unset($path[$i-1]);
  359.                 $path = array_values($path);
  360.                 $i -= 2;
  361.  
  362.             } elseif ($path[$i] == '..' AND $i == 1 AND $path[0] == '') {
  363.                 unset($path[$i]);
  364.                 $path = array_values($path);
  365.                 $i--;
  366.  
  367.             } else {
  368.                 continue;
  369.             }
  370.         }
  371.  
  372.         return implode('/', $path);
  373.     }
  374.  
  375.     /**
  376.     * Returns the standard port number for a protocol
  377.     *
  378.     * @param  string  $scheme The protocol to lookup
  379.     * @return integer         Port number or NULL if no scheme matches
  380.     *
  381.     * @author Philippe Jausions <Philippe.Jausions@11abacus.com>
  382.     */
  383.     function getStandardPort($scheme)
  384.     {
  385.         switch (strtolower($scheme)) {
  386.             case 'http':    return 80;
  387.             case 'https':   return 443;
  388.             case 'ftp':     return 21;
  389.             case 'imap':    return 143;
  390.             case 'imaps':   return 993;
  391.             case 'pop3':    return 110;
  392.             case 'pop3s':   return 995;
  393.             default:        return null;
  394.        }
  395.     }
  396.  
  397.     /**
  398.     * Forces the URL to a particular protocol
  399.     *
  400.     * @param string  $protocol Protocol to force the URL to
  401.     * @param integer $port     Optional port (standard port is used by default)
  402.     */
  403.     function setProtocol($protocol, $port = null)
  404.     {
  405.         $this->protocol = $protocol;
  406.         $this->port = is_null($port) ? $this->getStandardPort() : $port;
  407.     }
  408.  
  409. }
  410. ?>
  411.